﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using turnos.core.modelo;
using turnos.core.util;
using turnos.core.extensiones;



namespace turnos.data.dao
{
    public class TurnosDao
    {
        /*=== Variables de instancia ===*/
        #region Variables de instancia

        string _cnx;
        #endregion


        /*=== Propiedades ===*/
        #region Propiedades



        #endregion


        /*=== Métodos estáticos ===*/
        #region Métodos estáticos
        #endregion


        /*=== Constructores ===*/
        #region Constructores
        public TurnosDao(string cnx)
        {
            _cnx = cnx;
        }
        #endregion


        /*=== Métodos ===*/
        #region Métodos Escenarios
        /*private List<SEGUsuarios> cargarUsuarios(HAEscenario e)
        {
            e.SEGUsuarios.Load();
            return e.SEGUsuarios.ToList();
        }
        public List<HAEscenario> TraerEscenarios(SEGUsuarios usuario, int? idEscenario)
        {
            var escenarios = new List<HAEscenario>();
            if (idEscenario == null)
                if (usuario == null)
                    escenarios = (from e in Modelo.HAEscenario
                                  select e).ToList();
                else
                    escenarios = (from e in Modelo.HAEscenario
                                  from u in e.SEGUsuarios
                                  where u.id == usuario.id
                                  select e).ToList();
            else
                if (usuario == null)
                    escenarios = Modelo.HAEscenario.Where(c => c.IdEscenario == idEscenario.Value).ToList();
                else
                    escenarios = (from e in Modelo.HAEscenario
                                  from u in e.SEGUsuarios
                                  where u.id == usuario.id && e.IdEscenario == idEscenario
                                  select e).ToList();

            return escenarios;
        }



        public List<SEGUsuarios> TraerUsuarioEscenarios(HAEscenario Escenario)
        {
            var usuarios = new List<SEGUsuarios>();
            if (Escenario == null)
                throw new haberesException(haberesCts.NO_SELECCIONO_ESCENARIO);
            else
                usuarios = Escenario.SEGUsuarios.ToList();

            return usuarios;
        }

        public List<HACabecera> TraerTiposLiquidacionEscenarios(HAEscenario Escenario)
        {
            var tipos = new List<HACabecera>();
            if (Escenario == null)
                tipos = (from a in Modelo.HACabecera
                         select a).ToList();
            else
                tipos = (from a in Modelo.HAEscenarioCabecera
                         where a.RefEscenario == Escenario.IdEscenario
                         select a.HACabecera).ToList();

            return tipos;
        }


        public List<PersonasALiquidar> TraerDatosPreliquidacion(byte idEscenario, int? idPersona)
        {
            return Modelo.TraePersonasPorEscenario(idEscenario, idPersona).ToList();
        }
        */
        #endregion


        public Usuarios TraerUsuarioPorLogin(string login)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Usuarios retorno = (from u in Modelo.Usuarios
                                    where u.Usuario == login
                                    select u).SingleOrDefault();
                return retorno;
            }
        }

        public void GuardarMatriz(MatrizDeTurnos Matriz, string usuario)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Modelo.AltaModificacionMatriz(Matriz.IdMatriz, Matriz.Fecha, Matriz.CantPuestos, Matriz.CantHorasLab, Matriz.TiempoMinimo, Matriz.HoraInicio, usuario);
                Modelo.SaveChanges();
            }
        }

        public MatrizDeTurnos TraerMatrizPorFecha(DateTime fecha)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                MatrizDeTurnos resultado = (from m in Modelo.MatrizDeTurnos
                                            where m.Fecha == fecha
                                            select m).SingleOrDefault();
                return resultado;
            }

        }

        public List<MatrizDeTurnos> TraerMatrices()
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<MatrizDeTurnos> resultado = (from m in Modelo.MatrizDeTurnos
                                                  select m).OrderByDescending(x => x.Fecha).ToList();
                return resultado;
            }

        }

        public void EliminarMatriz(MatrizDeTurnos MatrizSeleccionada)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                MatrizDeTurnos borrar = (from m in Modelo.MatrizDeTurnos
                                         where m.IdMatriz == MatrizSeleccionada.IdMatriz
                                         select m).SingleOrDefault();
                if (borrar == null)
                    throw new turnosException(turnosCts.Format(turnosCts.ERROR_AL_BORRAR, "Matriz de Turnos"));

                Modelo.DeleteObject(borrar);
                Modelo.SaveChanges();
            }
        }

        public AgendaDeTurnos GuardarAgenda(int? IdTurno, int RefMatriz, short? Numero, DateTime FechayHora, byte? RefEstado, bool? pasoPorVisor, int? RefSolicitante, int? RefTipoTramite, byte? Puesto, string usuario)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                if (RefEstado == null || RefSolicitante == null)
                {
                    RefEstado = turnosCts.ID_ESTADO_LIBRE;
                }

                Modelo.AltaModificacionAgenda(IdTurno, RefMatriz, Numero, FechayHora, RefEstado, pasoPorVisor, RefSolicitante, RefTipoTramite, Puesto, usuario);
                Modelo.SaveChanges();

                return Modelo.AgendaDeTurnos.OrderByDescending(x => x.IdTurno).FirstOrDefault();
            }
        }


        public List<AgendaDeTurnos> TraerAgendaPorFecha(DateTime dateTime, byte? refEstado, byte? puesto)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<AgendaDeTurnos> resultado = (from a in Modelo.AgendaDeTurnos
                                                  where a.MatrizDeTurnos.Fecha.Day == dateTime.Day &&
                                                        a.MatrizDeTurnos.Fecha.Month == dateTime.Month &&
                                                        a.MatrizDeTurnos.Fecha.Year == dateTime.Year &&
                                                        (refEstado == null || a.RefEstado == 3 || a.RefEstado == refEstado)&&
                                                        (puesto == null || a.Puesto == puesto)

                                                  select a).OrderBy(x => x.FechayHora).ToList();
                foreach (var item in resultado)
                {
                    item.AgendaDeTurnosEstadosReference.Load();
                    item.SolicitantesReference.Load();
                    item.TipoTramiteReference.Load();
                    item.MatrizDeTurnosReference.Load();
                }
                return resultado;
            }
        }


        public AgendaDeTurnos TraerAgendaPorFechaConPuesto(DateTime dateTime, byte? refEstado)
        {
            AgendaDeTurnos resultado = null;
            using (var Modelo = new TurnosEntities(_cnx))
            {
                resultado = (from a in Modelo.AgendaDeTurnos
                             where a.MatrizDeTurnos.Fecha.Day == dateTime.Day &&
                                   a.MatrizDeTurnos.Fecha.Month == dateTime.Month &&
                                   a.MatrizDeTurnos.Fecha.Year == dateTime.Year &&
                                   (refEstado == null || a.RefEstado == refEstado) &&
                                   (a.PasoPorVisor == null || a.PasoPorVisor == false)

                             select a).OrderBy(x => x.FechayHora).FirstOrDefault();
                if (resultado != null)
                {
                    resultado.AgendaDeTurnosEstadosReference.Load();
                    resultado.SolicitantesReference.Load();
                    resultado.TipoTramiteReference.Load();
                    resultado.MatrizDeTurnosReference.Load();
                }
            }
            return resultado;
        }


        public AgendaDeTurnos TraerAgendaPorId(int idTurno)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                AgendaDeTurnos resultado = (from a in Modelo.AgendaDeTurnos
                                            where a.IdTurno == idTurno
                                            select a).SingleOrDefault();
                resultado.AgendaDeTurnosEstadosReference.Load();
                resultado.SolicitantesReference.Load();
                resultado.MatrizDeTurnosReference.Load();
                return resultado;
            }
        }

        public List<TiposDocumento> TraerTiposDeDocumento(Byte? idTipoDocumento)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<TiposDocumento> resultado =
                                            (from a in Modelo.TiposDocumento
                                             where idTipoDocumento == null || a.IdTipoDocumento == idTipoDocumento
                                             select a).ToList();
                return resultado;
            }
        }

        public List<AgendaDeTurnos> TraerSolicitudesDelSolicitante(byte tipoDocumento, int nroDocumento, string sexo)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<AgendaDeTurnos> resultado =
                                            (from a in Modelo.AgendaDeTurnos
                                             
                                             where a.Solicitantes.TiposDocumento.IdTipoDocumento == tipoDocumento &&
                                                    a.Solicitantes.NroDocumento == nroDocumento &&
                                                    a.Solicitantes.Sexo == sexo
                                             select a).ToList();
                foreach (var item in resultado)
                {
                    item.MatrizDeTurnosReference.Load();
                }
                return resultado;
            }
        }
        public Solicitantes TraerSolicitante(byte tipoDocumento, int nroDocumento, string sexo)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Solicitantes resultado =
                                            (from a in Modelo.Solicitantes
                                             where a.RefTipoDocumento == tipoDocumento &&
                                                    a.NroDocumento == nroDocumento &&
                                                    a.Sexo == sexo
                                             select a).SingleOrDefault();
                if (resultado != null)
                    resultado.TiposDocumentoReference.Load();
                return resultado;
            }
        }

        public void GuardarSolicitante(Solicitantes solicitante, AgendaDeTurnos agenda, string usuario)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Modelo.AltaModificacionAgenda(agenda.IdTurno, agenda.RefMatriz, agenda.Numero, agenda.FechayHora, agenda.RefEstado, agenda.PasoPorVisor, agenda.RefSolicitante, agenda.RefTipoTramite, agenda.Puesto, usuario);
                Modelo.AltaModificacionSolicitante(solicitante.IdSolicitante, agenda.IdTurno, solicitante.RefTipoDocumento, solicitante.NroDocumento, solicitante.Sexo, solicitante.ApeyNom, solicitante.Email, solicitante.FechaProxVenc, usuario);
                Modelo.SaveChanges();
            }
        }

        public void EliminarAgenda(AgendaDeTurnos agenda)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                AgendaDeTurnos borrar = (from m in Modelo.AgendaDeTurnos
                                         where m.IdTurno == agenda.IdTurno
                                         select m).SingleOrDefault();
                if (borrar == null)
                    throw new turnosException(turnosCts.Format(turnosCts.ERROR_AL_BORRAR, "La agenda"));

                Modelo.DeleteObject(borrar);
                Modelo.SaveChanges();
            }
        }

        public Solicitantes TraerSolicitantePorId(int idSolicitante)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Solicitantes sol = (from m in Modelo.Solicitantes
                                    where m.IdSolicitante == idSolicitante
                                    select m).SingleOrDefault();
                return sol;
            }
        }

        public List<AgendaDeTurnos> TraerSolicitantePorNombre(string nombre)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<AgendaDeTurnos> sol = (from m in Modelo.AgendaDeTurnos
                                            where m.Solicitantes.ApeyNom.Contains(nombre)
                                            select m).ToList();

                foreach (var item in sol)
                {
                    item.AgendaDeTurnosEstadosReference.Load();
                    item.SolicitantesReference.Load();
                    item.TipoTramiteReference.Load();
                    item.MatrizDeTurnosReference.Load();
                }

                return sol;
            }
        }

        public List<AgendaDeTurnos> TraerSolicitantePorDocumento(int nro)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<AgendaDeTurnos> sol = (from m in Modelo.AgendaDeTurnos
                                            where m.Solicitantes.NroDocumento == nro
                                            select m).ToList();
                foreach (var item in sol)
                {
                    item.AgendaDeTurnosEstadosReference.Load();
                    item.SolicitantesReference.Load();
                    item.TipoTramiteReference.Load();
                    item.MatrizDeTurnosReference.Load();
                }

                return sol;
            }
        }

        public List<Usuarios> TraerUsuarios()
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<Usuarios> us = (from m in Modelo.Usuarios
                                     select m).ToList();
                return us;
            }
        }

        public void GuardarUsuario(string idusuario, string usuario, string calve, string rol, string puesto)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                Usuarios us = (from m in Modelo.Usuarios
                               where m.Usuario == usuario
                               select m).SingleOrDefault();
                if (us == null)
                {
                    us = new Usuarios();
                    us.Usuario = usuario;
                    us.Contraseña = calve;
                    us.Rol = rol;
                    us.Puesto = puesto;
                    Modelo.AddToUsuarios(us);
                }
                else
                {
                    us.Usuario = usuario;
                    us.Contraseña = calve;
                    us.Rol = rol;
                    us.Puesto = puesto;

                }
                Modelo.SaveChanges();
            }
        }

        public List<TipoTramite> TraerTiposTramites(byte? idTipoTramite)
        {
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<TipoTramite> tms = (from m in Modelo.TipoTramite
                                         where (idTipoTramite == null || m.IdTipoTramite == idTipoTramite) && m.Activo
                                         select m).ToList();
                return tms;
            }
        }

        public List<Fecha> TraerFechasAgendas()
        {
            List<Fecha> ret = new List<Fecha>();
            using (var Modelo = new TurnosEntities(_cnx))
            {
                List<DateTime> tms = (from m in Modelo.MatrizDeTurnos
                                    select m.Fecha 
                                    ).OrderByDescending(x=>x).ToList();
                
                foreach (DateTime date in tms)
	            {
		             Fecha f = new Fecha(date.ToShortDateString());
                    if (  date > DateTime.Now.AddDays(-1) && date < DateTime.Now.AddDays(30))
                     ret.Add(f);
	            }
                return ret;
            }
        }


    }
}